package ws.very.web.tpl

import scala.collection.immutable.StringLike
import scala.collection.mutable.ListBuffer

/**
 * Content type used in default HTML templates.
 *
 * @param text the HTML text
 */
/**
 * Generic type representing content to be sent over an HTTP response.
 */
trait Content {

  /**
   * The content String.
   */
  def body: String

  /**
   * The default Content type to use for this content.
   */
  def contentType: String

}

trait BufferStrLike extends CharSequence {
  protected def buffer: StringBuilder
  override def length = buffer.length
  override def charAt(index: Int) = buffer.charAt(index)
  override def subSequence(start: Int, end: Int) = buffer.subSequence(start, end)

}

//case class Html(text: String) extends Appendable[Html] with Content with BufferStrLike {
//
//  lazy val buffer: StringBuilder = {
//    htmlBuffer.foldLeft(new StringBuilder(text)) { (older, newer) => older.append(newer.buffer) }
//  }
//  private val htmlBuffer = new ListBuffer[Html]
//
//  /**
//   * Appends this HTML fragment to another.
//   */
//  def +(other: Html): Html = {
//    htmlBuffer.append(other)
//    this
//  }
//  override def toString = buffer.toString
//
//  /**
//   * Content type of HTML (`text/html`).
//   */
//  def contentType: String = "text/html"
//
//  def body: String = toString
//
//}
case class Html(text: String) extends Appendable[Html] with Content with BufferStrLike // with play.mvc.Content   FIXME:
{
  val buffer = new StringBuilder(text)

  /**
   * Appends this HTML fragment to another.
   */
  def +(other: Html): Html = {
    buffer.append(other.buffer)
    this
  }
  override def toString = buffer.toString

  /**
   * Content type of HTML (`text/html`).
   */
  def contentType: String = "text/html"

  def body: String = toString

}

/**
 * Helper for HTML utility methods.
 */
object Html {

  /**
   * Creates an empty HTML fragment.
   */
  def empty: Html = Html("")

}

/**
 * Content type used in default text templates.
 *
 * @param text The plain text.
 */
case class Txt(text: String) extends Appendable[Txt] with Content with BufferStrLike // with play.mvc.Content   FIXME:
{
  val buffer = new StringBuilder(text)

  /**
   * Appends this text fragment to another.
   */
  def +(other: Txt): this.type = {
    buffer.append(other.buffer)
    this
  }

  override def toString = buffer.toString

  /**
   * Content type of text (`text/plain`).
   */
  def contentType = "text/plain"

  def body = toString

}

/**
 * Helper for utilities Txt methods.
 */
object Txt {

  /**
   * Creates an empty text fragment.
   */
  def empty = Txt("")

}

/**
 * Content type used in default XML templates.
 *
 * @param text the plain xml text
 */
case class Xml(text: String) extends Appendable[Xml] with Content with BufferStrLike //with play.mvc.Content FIXME:
{
  val buffer = new StringBuilder(text)

  /** Append this XML fragment to another. */
  def +(other: Xml) = {
    buffer.append(other.buffer)
    this
  }
  override def toString = buffer.toString

  /**
   * Content type of XML (`text/xml`).
   */
  def contentType = "text/xml"

  def body = toString

}

/**
 * Helper for XML utility methods.
 */
object Xml {

  /**
   * Create an empty XML fragment.
   */
  def empty = Xml("")

}

/** Defines a magic helper for Play templates. */
object CookieMagic {

  /**
   * Generates a set of valid HTML attributes.
   *
   * For example:
   * {{{
   * toHtmlArgs(Seq('id -> "item", 'style -> "color:red"))
   * }}}
   */
  def toHtmlArgs(args: Map[Symbol, Any]) = Html(args.map(a => a._1.name + "=\"" + a._2 + "\"").mkString(" "))

}

